package com.nulldev.util.internal.backport.httpclient_rw.impl.frame;

import java.nio.ByteBuffer;
import java.util.List;

import com.nulldev.util.internal.backport.concurrency9.Lists;

public class HeadersFrame extends HeaderFrame {

	public static final int TYPE = 0x1;

	// Flags
	public static final int END_STREAM = 0x1;
	public static final int PADDED = 0x8;
	public static final int PRIORITY = 0x20;

	private int padLength;
	private int streamDependency;
	private int weight;
	private boolean exclusive;

	public HeadersFrame(int streamid, int flags, List<ByteBuffer> headerBlocks, int padLength) {
		super(streamid, flags, headerBlocks);
		if (padLength > 0) {
			setPadLength(padLength);
		}
	}

	public HeadersFrame(int streamid, int flags, List<ByteBuffer> headerBlocks) {
		super(streamid, flags, headerBlocks);
	}

	public HeadersFrame(int streamid, int flags, ByteBuffer headerBlock) {
		this(streamid, flags, Lists.of(headerBlock));
	}

	@Override
	public int type() {
		return TYPE;
	}

	@Override
	int length() {
		return headerLength + ((flags & PADDED) != 0 ? (1 + padLength) : 0) + ((flags & PRIORITY) != 0 ? 5 : 0);
	}

	@Override
	public String flagAsString(int flag) {
		switch (flag) {
			case END_STREAM:
				return "END_STREAM";
			case PADDED:
				return "PADDED";
			case PRIORITY:
				return "PRIORITY";
		}
		return super.flagAsString(flag);
	}

	public void setPadLength(int padLength) {
		this.padLength = padLength;
		flags |= PADDED;
	}

	int getPadLength() {
		return padLength;
	}

	public void setPriority(int streamDependency, boolean exclusive, int weight) {
		this.streamDependency = streamDependency;
		this.exclusive = exclusive;
		this.weight = weight;
		this.flags |= PRIORITY;
	}

	public int getStreamDependency() {
		return streamDependency;
	}

	public int getWeight() {
		return weight;
	}

	public boolean getExclusive() {
		return exclusive;
	}

}
